﻿using System;
using System.Collections.Generic;

namespace SPALM
{
	using System.Text;
	using Microsoft.Build.Utilities;
	using Microsoft.Build.Framework;
	using System.Globalization;
	using System.IO;
	using System.Reflection;
  using System.ComponentModel;

	/// <summary>
	/// Checks conditions e.g. to be used before a deployment
	/// </summary>
  [Category("Wizard Dialogs")]
  [Description("Provides dialogs to request parameters from the user.")]
	public class Dialogs : BaseTask
	{
		private const string SelectWebApplicationAction = "SelectWebApplication";
		private const string SelectSiteAction = "SelectSiteCollections";
		private const string SelectWebAction = "SelectWeb";
		private const string StatusAction = "Status";
		private const string EnterUserCredentials = "UserCredentials";
		private const string Prompt = "Prompt";

		[DropdownValue(SelectWebApplicationAction)]
		[DropdownValue(SelectSiteAction)]
		[DropdownValue(SelectWebAction)]
		[DropdownValue(StatusAction)]
		[DropdownValue(EnterUserCredentials)]
		[DropdownValue(Prompt)]
		public override string TaskAction
		{
			get { return base.TaskAction; }
			set { base.TaskAction = value; }
		}

		[TaskAction(SelectWebApplicationAction, false)]
		[TaskAction(SelectSiteAction, false)]
		[TaskAction(SelectWebAction, false)]
		[TaskAction(StatusAction, false)]
		[TaskAction(EnterUserCredentials, false)]
		[TaskAction(Prompt, false)]
    [Description("Title of the wizard form")]
		public string Title { get; set; }

		[TaskAction(SelectWebApplicationAction, false)]
		[TaskAction(SelectSiteAction, false)]
		[TaskAction(SelectWebAction, false)]
		[TaskAction(StatusAction, false)]
		[TaskAction(EnterUserCredentials, false)]
		[TaskAction(Prompt, false)]
    [Description("Displayed text on the wizard")]
		public string HelpText { get; set; }

		[Output]
		[TaskAction(SelectWebApplicationAction, false)]
		[TaskAction(SelectSiteAction, false)]
		[TaskAction(SelectWebAction, false)]
    [Description("Entered values by the user")]
		public ITaskItem[] UserSelection { get; set; }

		[Output]
		[TaskAction(Prompt, false)]
    [Description("Entered value by the user")]
		public string UserResponse { get; set; }

		[Output]
		[TaskAction(EnterUserCredentials, false)]
    [Description("Entered username by the user")]
		public string UserName { get; set; }

		[Output]
		[TaskAction(EnterUserCredentials, false)]
    [Description("Entered password by the user")]
		public string Password { get; set; }

		protected override void InternalExecute()
		{
			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

			if (!string.IsNullOrEmpty(this.Title))
			{
				System.Console.Title = this.Title;
			}

			switch (this.TaskAction)
			{
				case SelectWebApplicationAction:
					this.SelectWebApplication();
					break;
                case SelectSiteAction:
                    this.SelectSiteCollections();
                    break;
				case StatusAction:
					this.ShowStatusForm();
					break;
				case EnterUserCredentials:
					this.ShowUserCredentialsForm();
					break;
				case Prompt:
					this.ShowPromptForm();
					break;
					
			}
		}

    [Description("Show a form with a single input value")]
		private void ShowPromptForm()
		{
			using (PromptForm form = new PromptForm(this.Title, this.HelpText))
			{
				if (form.ShowDialog() != System.Windows.Forms.DialogResult.OK)
				{
					Log.LogError("User credentials form has been cancelled.");
				}
				this.UserResponse = form.enteredValue;
			}
		}

    [Description("Show a form with user credentials")]
		private void ShowUserCredentialsForm()
		{
			using (UserCredentialsForm form = new UserCredentialsForm(this.Title, this.HelpText, this.UserName))
			{
				if (form.ShowDialog() != System.Windows.Forms.DialogResult.OK)
				{
					Log.LogError("User credentials form has been cancelled.");
				}
				this.UserName = form.enteredUserName;
				this.Password = form.enteredPassword;
			}
		}

    [Description("Show a simple form with text")]
		private void ShowStatusForm()
		{
			using (Status form = new Status(this.Title, this.HelpText))
			{
				if (form.ShowDialog() != System.Windows.Forms.DialogResult.OK)
				{
					Log.LogError("Status form has been cancelled.");
				}
			}
		}

		#region Helpers 

		static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			string assemblySearchDir = GetSharePointHive() + @"\ISAPI";

			string[] asmName = args.Name.Split(',');
			string asmPath = Path.Combine(assemblySearchDir, asmName[0] + ".dll");

			if (!File.Exists(asmPath))
			{
				throw (new Exception("Assembly " + asmName[0] + " not found in " + assemblySearchDir));
			}

			return Assembly.LoadFile(asmPath, Assembly.GetExecutingAssembly().Evidence);
		}

		internal static string GetSharePointHive()
		{
			return GetCommonProgramsFolder() + "\\Microsoft Shared\\web server extensions\\" + GetInstalledSharePointVersion();
		}

		public static string GetCommonProgramsFolder()
		{
			string commonProgramFolder = System.Environment.GetEnvironmentVariable("CommonProgramW6432");
			if (string.IsNullOrEmpty(commonProgramFolder))
			{
				commonProgramFolder = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles);
			}
			return commonProgramFolder;
		}

		internal static string GetInstalledSharePointVersion()
		{
			//is there a folder /14/Template, check only for 12 or 14 is not enough because 
			//folder 12 is sometimes also on 14er installations available (with bin folder)
			string check14Folder = GetCommonProgramsFolder() + "\\Microsoft Shared\\web server extensions\\" + 14 + "\\Template";
			if (Directory.Exists(check14Folder))
			{
				return "14";
			}
			return "12";
		}

		#endregion

    [Description("Show a form where user can select one or multiple web applications")]
		private void SelectWebApplication()
		{
			using (WebApplicationSelector form = new WebApplicationSelector(this.Title, this.HelpText))
			{
				if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
				{
					this.UserSelection = (ITaskItem[])form.taskItems.ToArray(typeof(ITaskItem));
				}
				else
				{
					Log.LogError("Web application selection has been cancelled.");
				}
			}
		}

    [Description("Show a form where user can select one or multiple site collections")]
    private void SelectSiteCollections()
		{
            using (SiteCollectionSelector form = new SiteCollectionSelector(this.Title, this.HelpText))
			{
				if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
				{
					this.UserSelection = (ITaskItem[])form.taskItems.ToArray(typeof(ITaskItem));
				}
				else
				{
					Log.LogError("Site collection selection has been cancelled.");
				}
			}
		}
	}
}
